home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / intrfc70.zip / NAMELIST.PAS < prev    next >
Pascal/Delphi Source File  |  1994-03-16  |  41KB  |  1,399 lines

  1. unit namelist;
  2. {$I SWITCHES.INC}
  3. { These are the routines that print the name definitions }
  4.  
  5. interface
  6.  
  7. uses
  8.   dump,util,globals,loader,head,nametype;
  9.  
  10. var
  11.   last_kind : byte;
  12.   in_function : boolean;
  13.   NowEnum: type_def_ptr;
  14.  
  15. procedure print_name_list(obj_list:list_ptr);
  16. procedure print_obj(obj:obj_ptr);
  17. procedure write_type_info(var name:string; obj:obj_ptr; info:type_info_ptr);
  18. function find_type(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  19. function find_type_or_proc(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  20. function find_proc_with_entry(in_unit:unit_list_ptr;entry:word):string;
  21. procedure write_var_type(type_unit,type_def_ofs:word);
  22. procedure write_var_info(var name:string; info:var_info_ptr);
  23. procedure write_enum_const(type_obj:type_def_ptr;val:longint);
  24. procedure write_const_type(var Val;type_unit,type_def_ofs:word;buffer:pointer);
  25. procedure write_args(arg:arg_ptr; num_args:word);
  26. procedure write_proc_type(var name:string; flags:code_flags; info:func_type_ptr);
  27. procedure write_proc_info(var name:string; info:func_info_ptr);
  28. procedure write_const_info(var name:string; info:const_info_ptr);
  29. procedure write_system_type(var name:string; kind:byte; info:system_info_ptr);
  30. procedure write_general(kind:byte; title,name,suffix:string);
  31. function find_name(unit_rec:unit_list_ptr;info_ofs:word):string;
  32. {  Unreliable way to get a name from a pointer to its info }
  33.  
  34.  
  35. implementation
  36.  
  37. uses
  38.   blocks,objects;
  39.  
  40. const
  41.   semicrlf = ';'+^M+^J;
  42.  
  43.  
  44. function obj_ofs(obj:pointer):word;
  45. begin
  46.   obj_ofs := ptr_diff(obj,buffer);
  47. end;
  48.  
  49. function get_buffer(obj:pointer):pointer;
  50. begin
  51.   get_buffer := ptr(seg(obj^),0);
  52. end;
  53.  
  54. {$IFDEF UNIT60}
  55. procedure write_type_def(def:type_def_ptr);far;
  56. var
  57.   i : integer;
  58.   l : longint;
  59.   save_kind : byte;
  60.   field_list : list_ptr;
  61.   current : list_ptr;
  62.   obj : obj_ptr;
  63.   no_name : string;
  64.   save_in_array : boolean;
  65. begin
  66.   with def^ do
  67.   begin
  68.     if base_type in [1,2,4,6,8,$a,$e,$f,$10,$11,$12,$13,$15,$18,$19,$1a,$1b,
  69.                      $21,$22,$23] then
  70.       case base_type of
  71.         1 : write('untyped');
  72.         2 : write('shortint');
  73.         4 : write('integer');
  74.         6 : write('longint');
  75.         8 : write('byte');
  76.        $a : write('word');
  77.        $e : write('single');
  78.        $f : write('double');
  79.       $10 : write('extended');
  80.       $11 : write('real');
  81.       $12 : write('boolean');
  82.       $13 : write('char');
  83.       $15 : write('comp');
  84.       $18 : write('text');
  85.       $19 : write('file');
  86.       $1a : write('pointer');
  87.       $1b : write('string');
  88.       { TPW types }
  89.       $21 : write('wordbool');
  90.       $22 : write('longbool');
  91.       $23 : write('pchar');
  92.     end
  93.     else
  94.     begin
  95.       if base_type <> 0 then
  96.         WriteError('{ unrecognized base type '+hexbyte(base_type)+'}');
  97.       case type_type of
  98.         0 : write('untyped');
  99.         1 : begin                  {Array}
  100.               write('array[');
  101.               write_var_type(index_unit,index_ofs);
  102.               write('] of ');
  103.               write_var_type(element_unit,element_ofs);
  104.             end;
  105.         2 : begin                  {Record}
  106.               save_kind := last_kind;
  107.               last_kind := record_id;
  108.               writeln ('Record ');
  109.  
  110.               build_list(field_list,buffer,add_only_offset(buffer,hash_ofs));
  111.  
  112.               current := field_list;
  113.               inc(indentation,2);
  114.               while current^.offset < $ffff do
  115.               begin
  116.                 obj := add_only_offset(buffer,current^.offset);
  117.                 print_obj(obj);
  118.                 current := current^.next;
  119.               end;
  120.               dec(indentation);
  121.               indent;
  122.               dec(indentation);
  123.               write('end');
  124.               last_kind := save_kind;
  125.             end;
  126.  
  127.         3 : begin                  {Object}
  128.               save_kind := last_kind;
  129.               last_kind := object_id;
  130.               write ('Object');
  131.               if parent_unit <> 0 then
  132.               begin
  133.                 write('(');
  134.                 write_var_type(parent_unit,parent_ofs);
  135.                 write(')');
  136.               end;
  137.               write(tab,'{ vmt block ',hexword(handle));
  138.               if w10 <> 0 then
  139.                 write(' w10=',hexword(w10));
  140.               writeln('}');
  141.  
  142.               build_list(field_list,buffer,add_only_offset(buffer,hash_ofs));
  143.  
  144.               inc(indentation,2);
  145.               current := field_list;
  146.               while current^.offset < $ffff do
  147.               begin
  148.                 obj := add_only_offset(buffer,current^.offset);
  149.                 print_obj(obj);
  150.                 current := current^.next;
  151.               end;
  152.               dec(indentation);
  153.               indent;
  154.               write('end');
  155.               dec(indentation);
  156.               last_kind := save_kind;
  157.             end;
  158.  
  159.         4 : begin                  {File}
  160.               write('file');
  161.               if base_unit <> 0 then
  162.               begin
  163.                 write(' of ');
  164.                 write_var_type(base_unit,base_ofs);
  165.               end;
  166.             end;
  167.         5 : write('built-in text type');
  168.         6 : begin                  {function/procedure}
  169.               no_name := '';
  170.               write_proc_type(no_name,[],func_type_ptr(addr(return_ofs)));
  171.               writeln;
  172.             end;
  173.         7 : begin                  {Set}
  174.               write('set of ');
  175.               write_var_type(base_unit,base_ofs);
  176.             end;
  177.         8 : begin                  {Pointer}
  178.               write('^');
  179.               write_var_type(target_unit,target_ofs);
  180.             end;
  181.  
  182.         9 : begin                  {String}
  183.               write('string[',size-1,']');
  184.               {N.B. actually record is like array of char, but "string" with
  185.                     no length is different.}
  186.             end;
  187.        10 : write('built-in ',size,' byte 8087 type');    {8087}
  188.        11 : write('built-in 6-byte real');
  189.        12 : begin                  {Range}
  190.               write(lower,'..',upper);
  191.             end;
  192.        13 : write('built-in boolean');
  193.        14 : write('built-in char type');
  194.        15 : begin                  {Enumeration or subrange}
  195.               if (type_unit = unit_list[1]^.own_record)
  196.                  and (type_ofs = obj_ofs(def)) then
  197.               begin
  198.                 { Must be first definition }
  199.                 write('(');
  200.                 NowEnum:=type_def_ptr(Def);
  201.                 {  Assume following records are constant declarations  }
  202.                 obj := add_only_offset(def,30);
  203.                 for l:=lower to upper-1 do
  204.                 begin
  205.                   write(obj^.name,',');
  206.                   obj:=add_only_offset(obj,12+length(obj^.name));
  207.                 end;
  208.                 write(obj^.name,')');
  209.               end
  210.               else
  211.               begin
  212.                 { Must be subrange }
  213.                 obj := add_only_offset(get_unit(type_unit)^.buffer,type_ofs);
  214.                 obj := add_only_offset(obj,24);
  215.                 i := 0;
  216.                 while i < def^.lower do
  217.                 begin
  218.                   obj:=add_only_offset(obj,12+length(obj^.name));
  219.                   inc(i);
  220.                 end;
  221.                 write(obj^.name);
  222.                 while i < def^.upper do
  223.                 begin
  224.                   obj:=add_only_offset(obj,12+length(obj^.name));
  225.                   inc(i);
  226.                 end;
  227.                 write('..',obj^.name);
  228.               end;
  229.             end;
  230.        else
  231.             begin
  232.               WriteError('Type definition of type '+decword(type_type));
  233.               writeln(' otherbyte=',other_byte,'size=',size);
  234.               indent;
  235.               write(' junk=');
  236.               for i:=3 to 8 do
  237.                 write(who_knows[i]:6);
  238.               writeln;
  239.             end;
  240.       end;
  241.     end;
  242.   end;
  243. end;
  244. {$ELSE}
  245. procedure write_type_def(def:type_def_ptr);far;
  246. var
  247.   i : integer;
  248.   l : longint;
  249.   save_kind : byte;
  250.   field_list : list_ptr;
  251.   current : list_ptr;
  252.   obj : obj_ptr;
  253.   type_obj : type_def_ptr;
  254.   no_name : string;
  255.   save_in_array : boolean;
  256.   bt:byte;
  257. begin
  258.   with def^ do
  259.   begin
  260.     if base_type in [1,2,4,6,8,$a,$e,$f,$10,$11,$12,$13,$15,$18,$19,$1a,$1b,
  261.                      $21,$22,$23] then
  262.     begin
  263.       bt:=255;
  264.       case base_type of
  265.         1 : begin write('untyped');  bt:=0    end;
  266.         2 : begin write('shortint'); bt:=12;  end;
  267.         4 : begin write('integer');  bt:=12;  end;
  268.         6 : begin write('longint');  bt:=12;  end;
  269.         8 : begin write('byte');     bt:=12;  end;
  270.        $a : begin write('word');     bt:=12;  end;
  271.        $e : begin write('single');   bt:=10;  end;
  272.        $f : begin write('double');   bt:=10;  end;
  273.       $10 : begin write('extended'); bt:=10;  end;
  274.       $11 : begin write('real');     bt:=11;  end;
  275.       $12 : begin write('boolean');  bt:=13;  end;
  276.       $13 : begin write('char');     bt:=14;  end;
  277.       $15 : begin write('comp');     bt:=10;  end;
  278.       $18 : begin write('text');     bt:=5;   end;
  279.       $19 : begin write('file');     bt:=4;   end;
  280.       $1a : begin write('pointer');  bt:=8;   end;
  281.       $1b : begin write('string');   bt:=9;   end;
  282.       { TPW types }
  283.       $21 : begin write('wordbool'); bt:=13;  end;
  284.       $22 : begin write('longbool'); bt:=13;  end;
  285.       $23 : begin write('pchar');    bt:=8;   end;
  286.       end;
  287.       if type_type<>bt then
  288.         Write('{base type <-> type_type error}');
  289.     end
  290.     else
  291.     begin
  292.       if base_type <> 0 then
  293.         WriteError('{ unrecognized base type '+hexbyte(base_type)+'}');
  294.       case type_type of
  295.         0 : write('untyped');
  296.         1 : begin                  {Array}
  297.               write('array[');
  298.               write_var_type(index_unit,index_ofs);
  299.               write('] of ');
  300.               write_var_type(element_unit,element_ofs);
  301.             end;
  302.         2 : begin                  {Record}
  303.               save_kind := last_kind;
  304.               last_kind := record_id;
  305.               writeln ('Record ');
  306.  
  307.               build_list(field_list,buffer,add_only_offset(buffer,hash_ofs));
  308.  
  309.               current := field_list;
  310.               inc(indentation,2);
  311.               while current^.offset < $ffff do
  312.               begin
  313.                 obj := add_only_offset(buffer,current^.offset);
  314.                 print_obj(obj);
  315.                 current := current^.next;
  316.               end;
  317.               dec(indentation);
  318.               indent;
  319.               dec(indentation);
  320.               write('end');
  321.               last_kind := save_kind;
  322.             end;
  323.  
  324.         3 : begin                  {Object}
  325.               save_kind := last_kind;
  326.               last_kind := object_id;
  327.               write ('Object');
  328.               if parent_unit <> 0 then
  329.               begin
  330.                 write('(');
  331.                 write_var_type(parent_unit,parent_ofs);
  332.                 write(')');
  333.               end;
  334.               write(tab,'{ vmt block ',hexword(handle));
  335.               if w10 <> 0 then
  336.                 write(' w10=',hexword(w10));
  337.               writeln('}');
  338.  
  339.               build_list(field_list,buffer,add_only_offset(buffer,hash_ofs));
  340.  
  341.               inc(indentation,2);
  342.               current := field_list;
  343.               while current^.offset < $ffff do
  344.               begin
  345.                 obj := add_only_offset(buffer,current^.offset);
  346.                 print_obj(obj);
  347.                 current := current^.next;
  348.               end;
  349.               dec(indentation);
  350.               indent;
  351.               write('end');
  352.               dec(indentation);
  353.               last_kind := save_kind;
  354.             end;
  355.  
  356.         4 : begin                  {File}
  357.               write('file');
  358.               if base_unit <> 0 then
  359.               begin
  360.                 write(' of ');
  361.                 write_var_type(base_unit,base_ofs);
  362.               end;
  363.             end;
  364.         5 : write('built-in text type');
  365.         6 : begin                  {function/procedure}
  366.               no_name := '';
  367.               write_proc_type(no_name,[],func_type_ptr(addr(return_ofs)));
  368.             end;
  369.         7 : begin                  {Set}
  370.               write('set of ');
  371.               write_var_type(base_unit,base_ofs);
  372.             end;
  373.         8 : begin                  {Pointer}
  374.               write('^');
  375.               write_var_type(target_unit,target_ofs);
  376.             end;
  377.  
  378.         9 : begin                  {String}
  379.               write('string[',size-1,']');
  380.               {N.B. actually record is like array of char, but "string" with
  381.                     no length is different.}
  382.             end;
  383.        10 : write('built-in ',size,' byte 8087 type');    {8087}
  384.        11 : write('built-in 6-byte real');
  385.        12,13,14 : begin                  {Range}
  386.               write_const_type(lower,type_unit,type_ofs,
  387.                                get_buffer(def));
  388.               write('..');
  389.               write_const_type(upper,type_unit,type_ofs,
  390.                                get_buffer(def));
  391.             end;
  392.        15 : begin                  {Enumeration or subrange}
  393.               if (type_unit = unit_list[1]^.own_record)
  394.                  and (type_ofs = obj_ofs(def)) then
  395.               begin
  396.                 { Must be first definition }
  397.                 write('(');
  398.                 {  Assume following records are constant declarations  }
  399.                 for l:=lower to upper do
  400.                 begin
  401.                   if l<>lower then write(',');
  402.                   write_enum_const(def,l);
  403.                 end;
  404.                 NowEnum:=def;
  405.                 write(')');
  406.               end
  407.               else
  408.               begin
  409.                 { Must be subrange }
  410.                 type_obj := add_only_offset(get_unit(type_unit)^.buffer,type_ofs);
  411.                 write_enum_const(type_obj,def^.lower);
  412.                 write('..');
  413.                 write_enum_const(type_obj,def^.upper);
  414.               end;
  415.             end;
  416.        else
  417.             begin
  418.               WriteError('Type definition of type '+decword(type_type));
  419.               writeln(' otherbyte=',other_byte,'size=',size);
  420.               indent;
  421.               write(' junk=');
  422.               for i:=3 to 8 do
  423.                 write(who_knows[i]:6);
  424.               writeln;
  425.             end;
  426.       end;
  427.     end;
  428.   end;
  429. end;
  430. {$ENDIF}
  431.  
  432. procedure write_type_info(var name:string; obj:obj_ptr; info:type_info_ptr);
  433. var
  434.   def_obj : obj_ptr;
  435. begin
  436.   indent;
  437.   if (last_kind <> record_id) and (last_kind <> type_id) then
  438.   begin
  439.     writeln('type');
  440.     indent;
  441.     last_kind := type_id;
  442.   end;
  443.   write(oneindent,name,'=',oneindent);
  444.   with info^ do
  445.     if obj = find_type(get_unit(type_unit),type_def_ofs) then
  446.       write_type_def(add_only_offset(buffer,type_def_ofs))
  447.     else
  448.       write_var_type(type_unit,type_def_ofs);
  449.   writeln(';');
  450. end;
  451.  
  452. function find_type(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  453. var
  454.   current:list_ptr;
  455.   obj : obj_ptr;
  456.   obj_info : type_info_ptr;
  457. begin
  458.   with unit_rec^ do
  459.   begin
  460.     if (obj_list = nil) and (buffer <> nil) then
  461.       build_list(obj_list,buffer,add_only_offset(buffer,header_ptr(buffer)^.ofs_hashtable));
  462.     if obj_list <> nil then
  463.     begin
  464.       current := obj_list;
  465.       while current^.offset < $ffff do
  466.       begin
  467.         obj := add_only_offset(buffer,current^.offset);
  468.         obj_info := add_only_offset(obj,4+length(obj^.name));
  469.         if     (obj^.obj_type = type_id)
  470.            and (obj_info^.type_def_ofs = def_ofs)
  471.            and (obj_info^.type_unit = own_record) then
  472.         begin
  473.           find_type := obj;
  474.           exit;
  475.         end;
  476.         current := current^.next;
  477.       end;
  478.     end;
  479.     find_type := nil;
  480.   end;
  481. end;
  482.  
  483. function find_type_or_proc(unit_rec:unit_list_ptr;def_ofs:word):obj_ptr;
  484. var
  485.   current:list_ptr;
  486.   obj : obj_ptr;
  487.   obj_info : type_info_ptr;
  488. begin
  489.   with unit_rec^ do
  490.   begin
  491.     if (obj_list = nil) and (buffer <> nil) then
  492.       build_list(obj_list,buffer,add_only_offset(buffer,header_ptr(buffer)^.ofs_hashtable));
  493.     if obj_list <> nil then
  494.     begin
  495.       current := obj_list;
  496.       while current^.offset < $ffff do
  497.       begin
  498.         obj := add_only_offset(buffer,current^.offset);
  499.         obj_info := add_only_offset(obj,4+length(obj^.name));
  500.         if     ((obj^.obj_type = type_id)
  501.              and (obj_info^.type_def_ofs = def_ofs)
  502.              and (obj_info^.type_unit = own_record))
  503.           or
  504.              ((obj^.obj_type = proc_id)
  505.              and (ofs(obj^)=def_ofs))
  506.              then
  507.         begin
  508.           find_type_or_proc := obj;
  509.           exit;
  510.         end;
  511.         current := current^.next;
  512.       end;
  513.     end;
  514.     find_type_or_proc := nil;
  515.   end;
  516. end;
  517.  
  518. procedure make_proc_list_entry(var in_unit:unit_list_ptr);
  519. var
  520.   buffer:byte_array_ptr;
  521.   lname:string;
  522.  
  523. procedure fpe(obj_list:list_ptr;var proc_list:proc_list_ptr);
  524. var
  525.   current:list_ptr;
  526.   obj : obj_ptr;
  527.   obj_info : func_info_ptr;
  528.   obj_list2:list_ptr;
  529.   fp:string;
  530.   def:type_def_ptr;
  531.   lastlen:integer;
  532. procedure Insert(const name:string;Entry:word);
  533. var Aux:proc_list_ptr;
  534. begin
  535.   New(Aux);
  536.   Aux^.name:=NewStr(name);
  537.   Aux^.Entry:=Entry;
  538.   Aux^.Next:=proc_list;
  539.   proc_list:=aux;
  540. end;
  541.  
  542. begin
  543.   if obj_list <> nil then
  544.   begin
  545.     current := obj_list;
  546.     while current^.offset < $ffff do
  547.     begin
  548.       obj := add_only_offset(buffer,current^.offset);
  549.       obj_info := add_only_offset(obj,4+length(obj^.name));
  550.       if (obj^.obj_type = type_id) then
  551.       begin
  552.         if get_unit_buffer(buffer,type_info_ptr(obj_info)^.type_unit)^.buffer=buffer then
  553.         begin {only types defined in this unit }
  554.           def:=add_only_offset(buffer,type_info_ptr(obj_info)^.type_def_ofs);
  555.           if (def^.type_type=3) and (def^.hash_ofs<>0) then { object }
  556.           begin
  557.             build_list(obj_list2,buffer,add_only_offset(buffer,def^.hash_ofs));
  558.             lastlen:=length(lname);
  559.             lname:=lname+obj^.name+'.';
  560.             fpe(obj_list2,proc_list);
  561.             lname[0]:=char(lastlen);
  562.             destroy_list(obj_list2);
  563.           end;
  564.         end
  565.       end
  566.       else if ((obj^.obj_type and $7f) = proc_id) then
  567.       begin
  568.         Insert(lname+obj^.name,obj_info^.entry_ofs);
  569.         if (obj_info^.local_hash<>0) then
  570.         begin
  571.           build_list(obj_list2,buffer,add_only_offset(buffer,obj_info^.local_hash));
  572.           lastlen:=length(lname);
  573.           lname:=lname+obj^.name+'.';
  574.           fpe(obj_list2,proc_list);
  575.           lname[0]:=char(lastlen);
  576.           destroy_list(obj_list2);
  577.         end;
  578.       end;
  579.       current := current^.next;
  580.     end;
  581.   end;
  582. end;
  583.  
  584. begin
  585.   with in_unit^ do
  586.   begin
  587.     if (obj_list = nil) and (buffer <> nil) then
  588.       build_list(obj_list,buffer,add_only_offset(buffer,header_ptr(buffer)^.ofs_hashtable));
  589.   end;
  590.   buffer:=in_unit^.buffer;
  591.   in_unit^.proc_list:=nil;
  592.   lname:='';
  593.   fpe(in_unit^.obj_list,in_unit^.proc_list);
  594. end;
  595.  
  596. function find_proc_with_entry(in_unit:unit_list_ptr;entry:word):string;
  597. var
  598.   act:proc_list_ptr;
  599. begin
  600.   if entry=0 then
  601.   begin
  602.     find_proc_with_entry:='Startup code';
  603.     exit;
  604.   end;
  605.   find_proc_with_entry := '';
  606.   with in_unit^ do
  607.   begin
  608.     if (proc_list = nil) and (buffer <> nil) then
  609.       make_proc_list_entry(in_unit);
  610.   end;
  611.   act:=in_unit^.proc_list;
  612.   while act<>nil do
  613.   begin
  614.     if act^.entry=entry then
  615.     begin
  616.       find_proc_with_entry:=act^.name^;
  617.       break;
  618.     end;
  619.     act:=act^.next;
  620.   end;
  621. end;
  622.  
  623.  
  624. function find_name(unit_rec:unit_list_ptr;info_ofs:word):string;
  625. {  Unreliable way to get a name from a pointer to its info }
  626. var
  627.   i:word;
  628.   fname:string;
  629. begin
  630.   with unit_rec^ do
  631.   begin
  632.     if buffer <> nil then
  633.       for i:=info_ofs-2 downto 0 do
  634.         if i+buffer^[i]+1 = info_ofs then
  635.         begin
  636.           move(buffer^[i],fname[0],buffer^[i]+1);
  637.           find_name := fname;
  638.           exit;
  639.         end;
  640.   end;
  641.   find_name := '';
  642. end;
  643.  
  644. procedure write_var_type(type_unit,type_def_ofs:word);
  645. var
  646.   type_obj : obj_ptr;
  647.   unit_ptr : unit_list_ptr;
  648. begin
  649.   if type_unit > 0 then
  650.   begin
  651.     unit_ptr := get_unit(type_unit);
  652.     with unit_ptr^ do
  653.     begin
  654.       if buffer <> nil then
  655.       begin
  656.         type_obj := find_type(unit_ptr,type_def_ofs);
  657.         if type_obj <> nil then
  658.           write(type_obj^.name)
  659.         else
  660.           write_type_def(add_only_offset(buffer,type_def_ofs));
  661.       end
  662.       else
  663.         write(name,'.ofs',type_def_ofs);
  664.     end;
  665.   end
  666.   else
  667.     WriteError('type_unit not found');
  668. end;
  669.  
  670. procedure write_var_info(var name:string; info:var_info_ptr);
  671. var
  672.   orig_unit:unit_list_ptr;
  673.   f : var_flags;
  674. begin
  675.   indent;
  676.   with info^ do
  677.   begin
  678.     if not (last_kind in [object_id,objpriv_id,record_id]) then
  679.     begin
  680.       f := flags*[const_flag,local,referenced,const_arg];
  681.       if f = [] then
  682.         write_general(var_id,'var',name,':'+oneindent)
  683.       else if f = [const_flag] then
  684.         write_general(const_id,'const',name,':'+oneindent)
  685.       else if f = [const_flag,local] then
  686.         write_general(var_id,'var',name,':'+oneindent)
  687.       else if f = [local] then
  688.         write_general(local_id,'local var',name,':'+oneindent)
  689.       else if f = [local,referenced] then
  690.         write_general(referenced_id,'referenced var',name,':'+oneindent)
  691.       else if f = [local,referenced,const_arg] then
  692.         write_general(refconst_id,'referenced const',name,':'+oneindent)
  693.       else
  694.         WriteError(' var flags = '+hexbyte(byte(flags))+oneindent);
  695.       end
  696.     else
  697.       write(name,':',oneindent);
  698.  
  699.     write_var_type(type_unit,type_def_ofs);
  700.  
  701.     if absolute in flags then
  702.     begin
  703.       write(' absolute ');
  704.       orig_unit := get_unit(in_unit);
  705.       if orig_unit <> nil then
  706.       begin
  707.         if orig_unit <> unit_list[1] then
  708.           write(orig_unit^.name,'.');
  709.         writeln(find_name(orig_unit,offset),';');
  710.       end
  711.       else
  712.         WriteError('?????;');
  713.     end
  714.     else
  715.     begin
  716.       if const_flag in flags then
  717.         if local in flags then
  718.           write(' absolute $'+hexword(in_unit)+':$'+hexword(offset))
  719.         else
  720.           write('=',oneindent,'?');
  721.       if in_function and not (const_flag in flags) then
  722.       begin
  723.         write(';',tab,'{BP ofs ');
  724.         if integer(offset)<0 then
  725.           write('-')
  726.         else
  727.           write('+');
  728.         write(hexwordasm(abs(integer(offset))));
  729.         writeln('}');
  730.       end
  731.       else
  732.       begin
  733.         write(';');
  734.         if flags<>[const_flag,local] then
  735.         begin
  736.           write(tab,'{ofs ',hexwordblank(offset));
  737.           if not (last_kind in [record_id,object_id,objpriv_id]) then
  738.             write(' in block ',hexwordblank(in_unit));
  739.           write('}');
  740.         end;
  741.         writeln;
  742.       end;
  743.     end;
  744.     if v128 in flags then
  745.       WriteError('Unknown variable flag '+HexWord(Byte(flags)));
  746.   end;
  747. end;
  748.  
  749. procedure write_args(arg:arg_ptr;num_args:word);
  750. var
  751.   i:word;
  752. begin
  753.   writeln('(');
  754.   inc(indentation);
  755.   for i:=1 to num_args do
  756.   begin
  757.     with arg^ do
  758.     begin
  759.       indent;
  760.       if referenced in flags then
  761.         write('var   ')
  762.       else if const_arg in flags then
  763.         write('const ')
  764.       else
  765.         write('      ');
  766.       if flags - [referenced,const_arg] <> [local] then
  767.       begin
  768.         WriteError('{ flags ='+hexbyte(byte(flags))+' }');
  769.         indent;
  770.       end;
  771.       write('arg',i,':',oneindent);
  772.       write_var_type(type_unit,type_def_ofs);
  773.       if i<>num_args then
  774.         writeln(';')
  775.       else
  776.         writeln;
  777.     end;
  778.     arg := add_only_offset(arg,sizeof(arg_rec));
  779.   end;
  780.   indent;
  781.   write(')');
  782.   dec(indentation);
  783. end;
  784.  
  785. procedure write_locals(var name:string; info:func_info_ptr);
  786. var
  787.   obj_list : list_ptr;
  788.   save_in_function : boolean;
  789. begin
  790.   if info^.local_hash = 0 then
  791.     exit;
  792.   save_in_function := in_function;
  793.   in_function := true;
  794.   build_list(obj_list,buffer,add_only_offset(buffer,info^.local_hash));
  795.   inc(indentation);
  796.   indent; writeln('{ ',name,' locals begin...}');
  797.   print_name_list(obj_list);
  798.   indent; writeln('{ ...',name,' locals end.}');
  799.   writeln;
  800.   dec(indentation);
  801.   in_function := save_in_function;
  802. end;
  803.  
  804.  
  805. procedure write_proc_type(var name:string; flags:code_flags; info:func_type_ptr);
  806. var
  807.   proc : boolean;
  808. begin
  809.   with info^ do
  810.   begin
  811.     if (type_def_ofs = 0) and (type_unit = 0) then
  812.       proc := true
  813.     else
  814.       proc := false;
  815.     if construct in flags then
  816.       write('constructor',oneindent,name)
  817.     else if destruct in flags then
  818.       write('destructor',oneindent,name)
  819.     else
  820.       if proc then
  821.         write('procedure',oneindent,name)
  822.       else
  823.         write('function',oneindent,name);
  824.     if info^.num_args > 0 then
  825.       write_args(arg_ptr(add_only_offset(info,sizeof(func_type_rec))),
  826.                  info^.num_args);
  827.     if not proc then
  828.     begin
  829.       write(':',oneindent);
  830.       write_var_type(type_unit,type_def_ofs);
  831.     end;
  832.   end;
  833.   if Name<>'' then
  834.     write(';');
  835. end;
  836.  
  837. {$IFDEF UNIT60}
  838. procedure write_proc_info(var name:string; info:func_info_ptr);
  839. var
  840.   entry_pt : entry_pt_ptr;
  841.   code : ^word;
  842.   i : word;
  843.   unknown_flags : obj_flags;
  844. begin
  845.   indent;
  846.   with info^ do
  847.   begin
  848.     write_proc_type(name,code_type,func_type_ptr(addr(func_type)));
  849.     entry_pt := add_only_offset(buffer,header^.ofs_entry_pts+entry_ofs);
  850.  
  851.     if vmt_entry > 0 then
  852.     begin
  853.       write(' virtual');
  854.       if dynamic in obj_type then
  855.         write(' ',vmt_entry);
  856.       write(';');
  857.     end;
  858.  
  859.     if external_code in code_type then
  860.       write(' external;');
  861.     if assembler in code_type then
  862.       write(' assembler;');
  863.     if interrupt in code_type then
  864.       write(' interrupt;');
  865.  
  866.     if exported in obj_type then
  867.       write(' export;');
  868.     if windows_frame in obj_type then
  869.       write(' W+;');
  870.  
  871.     if from_dll in obj_type then
  872.     begin
  873.       write(' external ''',dll_name(entry_pt^.code_block),'''');
  874.       if by_name in obj_type then
  875.         write(' name ''',dll_name(entry_pt^.offset),'''')
  876.       else
  877.         write(' index ',entry_pt^.offset);
  878.       write(';');
  879.     end
  880.     else
  881.       if by_name in obj_type then
  882.         write(' Unexpected by_name flag!');
  883.  
  884.     if local_code in obj_type then
  885.       write(' local code;');
  886.  
  887.     unknown_flags := obj_type - [exported,windows_frame,from_dll,by_name,
  888.                                   dynamic,local_code];
  889.     if unknown_flags <> [] then
  890.       write(' Unrecognized object flags: ',hexbyte(byte(unknown_flags)));
  891.     if not (inline_code in code_type) then
  892.     begin
  893.       write(tab,'{ Proc ',hexwordblank(entry_ofs));
  894.       if not (from_dll in obj_type) then
  895.         write(' Entry ',hexwordblank(entry_pt^.code_block),':',
  896.                             hexword(entry_pt^.offset));
  897.       if (vmt_entry > 0) and not (dynamic in obj_type) then
  898.         write(' vmt index ',hexword(vmt_entry),'h');
  899.       writeln('}');
  900.     end
  901.     else
  902.     begin
  903.       writeln;
  904.       indent;
  905.       write(' Inline(');
  906.       code := add_only_offset(info,sizeof(func_info_rec)
  907.                              +func_type.num_args*sizeof(arg_rec));
  908.       for i:=1 to entry_ofs div 2 - 1 do
  909.       begin
  910.         write('$',hexbyte(hi(code^)):2,'/');
  911.         if lo(code^) <> 0 then
  912.           writeln('Low byte not zero!');
  913.         code := add_only_offset(code,sizeof(word));
  914.       end;
  915.       writeln('$',hexbyte(hi(code^)):2,');');
  916.       if lo(code^) <> 0 then
  917.         writeln('Low byte not zero!');
  918.     end;
  919.     if do_locals in active_options then
  920.       write_locals(name,info);
  921.   end;
  922. end;
  923. {$ELSE}
  924.  
  925. procedure write_proc_info(var name:string; info:func_info_ptr);
  926. type
  927.   inline_data_ptr = ^inline_data;
  928.   inline_data = record
  929.     itype:byte;
  930.     case integer of
  931.       0:(b:byte);
  932.       1:(w:word);
  933.       2:(offset,block,block_unit:word);
  934.     end;
  935. var
  936.   entry_pt : entry_pt_ptr;
  937.   code_ptr,codestart : inline_data_ptr;
  938.   i : word;
  939.   unknown_flags : obj_flags;
  940. begin
  941.   indent;
  942.   with info^ do
  943.   begin
  944.     write_proc_type(name,code_type,func_type_ptr(addr(func_type)));
  945.     entry_pt := add_only_offset(buffer,header^.ofs_entry_pts+entry_ofs);
  946.  
  947.     if vmt_entry > 0 then
  948.     begin
  949.       write(' virtual');
  950.       if dynamic in obj_type then
  951.         write(' ',vmt_entry);
  952.       write(';');
  953.     end;
  954.  
  955.     if external_code in code_type then
  956.       write(' external;');
  957.     if assembler in code_type then
  958.       write(' assembler;');
  959.     if interrupt in code_type then
  960.       write(' interrupt;');
  961.  
  962.     if exported in obj_type then
  963.       write(' export;');
  964.     if windows_frame in obj_type then
  965.       write(' W+;');
  966.  
  967.     if not (not_from_dll in obj_type) and
  968.        ([inline_code,external_code,interrupt,assembler]*code_type=[]) then
  969.     begin
  970.       write(' external ''',dll_name(entry_pt^.code_block),'''');
  971.       if ent_by_name in entry_pt^.flags then
  972.         write(' name ''',dll_name(entry_pt^.offset),'''')
  973.       else
  974.         write(' index ',entry_pt^.offset);
  975.       write(';');
  976.     end;
  977.  
  978.     unknown_flags := obj_type - [exported,windows_frame,not_from_dll,
  979.                                   dynamic];
  980.     if unknown_flags <> [] then
  981.       WriteError(' Unrecognized object flags: '+hexbyte(byte(unknown_flags)));
  982.     if not (inline_code in code_type) then
  983.     begin
  984.       write(tab,'{ Proc ',hexwordblank(entry_ofs));
  985.       if not_from_dll in obj_type then
  986.         write(' Entry ',hexwordblank(entry_pt^.code_block),':',
  987.                             hexword(entry_pt^.offset));
  988.       if (vmt_entry > 0) and not (dynamic in obj_type) then
  989.         write(' vmt index ',hexword(vmt_entry),'h');
  990.       writeln('}');
  991.     end
  992.     else
  993.     begin
  994.       writeln;
  995.       indent;
  996.       write(' Inline(');
  997.       codestart := add_only_offset(info,sizeof(func_info_rec)
  998.                              +func_type.num_args*sizeof(arg_rec));
  999.       i:=0;
  1000.       while i<entry_ofs do
  1001.       begin
  1002.         code_ptr := add_only_offset(codestart,i);
  1003.         case code_ptr^.itype of
  1004.         0 : begin
  1005.               write('<$',hexbyte(code_ptr^.b):2);
  1006.               Inc(i,2);
  1007.             end;
  1008.         1 : begin
  1009.               write('>$',hexword(code_ptr^.w):4);
  1010.               Inc(i,3);
  1011.             end;
  1012.         2,3 : begin
  1013.               write('{ofs ',hexwordblank(code_ptr^.offset),' in ');
  1014.               if code_ptr^.itype=2 then
  1015.                 write('var')
  1016.               else
  1017.                 write('const');
  1018.               write(' block ',hexwordblank(code_ptr^.block));
  1019.               write(' in unit ',get_unit_name(code_ptr^.block_unit));
  1020.               writeln('}');
  1021.               write('':10);
  1022.               Inc(i,7);
  1023.             end;
  1024.         else
  1025.           WriteError('Inline code unknown type!');
  1026.           Inc(i,1);
  1027.         end;
  1028.         if i=entry_ofs then
  1029.           writeln(');')
  1030.         else
  1031.           write('/');
  1032.       end;
  1033.     end;
  1034.     if (next_method<>0) and not (method in code_type) then
  1035.       WriteError('Unknown next_method value');
  1036.     if (w4<>$0d06) then
  1037.       WriteError('Unknown w4 value');
  1038.     if not (((w5=4) and not (method in code_type)) or
  1039.             ((w5=8) and (method in code_type))) then
  1040.       WriteError('Unknown w5 value');
  1041.     if (w6<>0) then
  1042.       WriteError('Unknown w6 value');
  1043.     if do_locals in active_options then
  1044.       write_locals(name,info);
  1045.   end;
  1046. end;
  1047. {$ENDIF}
  1048.  
  1049. procedure write_enum_const(type_obj:type_def_ptr;val:longint);
  1050. var obj : obj_ptr;
  1051.     i : integer;
  1052. begin
  1053.   if type_obj^.type_type<>15 then
  1054.   begin
  1055.     WriteError('Not enum const!?');
  1056.     exit;
  1057.   end;
  1058.   obj := add_only_offset(type_obj,32);
  1059.   i := 0;
  1060.   while i < val do
  1061.   begin
  1062.     obj:=add_only_offset(obj,12+length(obj^.name));
  1063.     inc(i);
  1064.   end;
  1065.   write(obj^.name);
  1066. end;
  1067.  
  1068. procedure write_const_type(var Val;type_unit,type_def_ofs:word;buffer:pointer);
  1069. var type_obj:type_def_ptr;
  1070.     last,l:longint;
  1071.     count,i,state:Integer;
  1072.     range:boolean;
  1073.     unit_ptr:unit_list_ptr;
  1074. begin
  1075.   if buffer<>nil then
  1076.     unit_ptr:=get_unit_buffer(buffer,type_unit)
  1077.   else
  1078.     unit_ptr:=get_unit(type_unit);
  1079.   with  unit_ptr^ do
  1080.   begin
  1081.     if buffer<>nil then
  1082.     begin
  1083.       type_obj:=add_only_offset(buffer,type_def_ofs);
  1084.       case type_obj^.type_type of
  1085.       9   { string }
  1086.          : begin
  1087.              state:=0;
  1088.              for i:=1 to length(string(val)) do
  1089.              begin
  1090.                if string(val)[i]<' ' then
  1091.                  case state of
  1092.                  0: begin
  1093.                      state:=2;
  1094.                      write('#$',hexbyte(ord(string(val)[i])));
  1095.                     end;
  1096.                  1: begin
  1097.                       write('''#$',hexbyte(ord(string(val)[i])));
  1098.                       state:=2;
  1099.                     end;
  1100.                  2: write('#$',hexbyte(ord(string(val)[i])));
  1101.                  end
  1102.                else
  1103.                  case state of
  1104.                  0,2: begin
  1105.                      state:=1;
  1106.                      write('''',string(val)[i]);
  1107.                     end;
  1108.                  1: write(string(val)[i]);
  1109.                  end;
  1110.              end;
  1111.            if state=1 then
  1112.              write('''');
  1113.            end;
  1114.       15  { enum }
  1115.          : begin
  1116.              if NowEnum=nil then
  1117.                write_enum_const(type_obj,longint(val))
  1118.              else
  1119.                write(integer(val));
  1120.            end;
  1121.       12  { int }
  1122.          : write(longint(val));
  1123.       13  { bool }
  1124.          : write(boolean(val));
  1125.       14  { char }
  1126.          : if (char(val)<' ') or (char(val)>#$fe) then
  1127.              write('#$',hexbyte(byte(val)))
  1128.            else
  1129.              write('''',char(val),'''');
  1130.       10  { extend }
  1131.          : write(extended(val));
  1132.       8   { pointer }
  1133.          : write('ptr($'+hexword(seg(pointer(val)^))+
  1134.                  ',$'+hexword(ofs(pointer(val)^))+')');
  1135.       7   { set }
  1136.          : begin
  1137.              write('[');
  1138.              Count:=0;
  1139.              last:=-2;
  1140.              Range:=False;
  1141.              for l:=0 to 255 do
  1142.                if l in tbyteset(val) then
  1143.                begin
  1144.                  if Range or (last=l-1) then
  1145.                    Range:=True
  1146.                  else
  1147.                  begin
  1148.                    inc(Count);
  1149.                    if Count>1 then
  1150.                      write(',');
  1151.                    write_const_type(l,type_obj^.base_unit,type_obj^.base_ofs,buffer);
  1152.                    last:=l;
  1153.                  end
  1154.                end
  1155.                else
  1156.                begin
  1157.                  if Range then
  1158.                  begin
  1159.                    Range:=False;
  1160.                    if last=l-2 then
  1161.                    begin
  1162.                      last:=l-1;
  1163.                      write(',');
  1164.                      write_const_type(last,type_obj^.base_unit,type_obj^.base_ofs,buffer);
  1165.                    end
  1166.                    else
  1167.                    begin
  1168.                      last:=l-1;
  1169.                      write('..');
  1170.                      write_const_type(last,type_obj^.base_unit,type_obj^.base_ofs,buffer);
  1171.                    end;
  1172.                  end;
  1173.                  last:=-2;
  1174.                end;
  1175.              write(']');
  1176.            end;
  1177.       else
  1178.         WriteError('Unknown type of constant');
  1179.       end;
  1180.     end
  1181.     else
  1182.       Write('?');
  1183.   end;
  1184. end;
  1185.  
  1186. procedure write_const_info(var name:string; info:const_info_ptr);
  1187. var
  1188.   type_obj : type_def_ptr;
  1189. begin
  1190.   indent;
  1191.   if (NowEnum<>nil) and ((info^.type_def_ofs<>Ofs(NowEnum^)) or
  1192.      (Seg(get_unit(info^.type_unit)^.buffer^)<>Seg(NowEnum^))) then
  1193.   begin
  1194.     Writeln('*)');
  1195.     NowEnum:=nil;
  1196.     last_kind:=init_id;
  1197.   end;
  1198.   if (last_kind <> record_id) and (last_kind <> const_id) then
  1199.   begin
  1200.     if NowEnum<>nil then
  1201.       Write('(* ');
  1202.     writeln('Const');
  1203.     indent;
  1204.     last_kind := const_id;
  1205.   end;
  1206.   write(oneindent,name,'=',oneindent);
  1207.   write_const_type(info^.allval,info^.type_unit,info^.type_def_ofs,nil);
  1208.   writeln(';');
  1209. end;
  1210.  
  1211. procedure write_unit_info(var name:string; info:unit_ptr; self:boolean);
  1212. begin
  1213.   indent;
  1214.   if self then
  1215.   begin
  1216.     write('Unit',oneindent,name,';');
  1217.     last_kind := init_id;
  1218.   end
  1219.   else
  1220.   begin
  1221.     if last_kind = unit_id then
  1222.     begin
  1223.       writeln;
  1224.       write(oneindent,',',name);
  1225.     end
  1226.     else
  1227.     begin
  1228.       write('Uses',oneindent,name);
  1229.       last_kind := unit_id;
  1230.     end;
  1231.   end;
  1232.   with info^ do
  1233.   begin
  1234.     write(tab,'{ checksum = ',hexword(checksum),'}');
  1235.     if self then
  1236.     begin
  1237.       writeln;
  1238.       writeln('interface');
  1239.     end;
  1240.   end;
  1241. end;
  1242.  
  1243. procedure write_system_type(var name:string; kind:byte; info:system_info_ptr);
  1244. begin
  1245.   if kind=sys_proc_id then
  1246.     write('procedure')
  1247.   else if kind=sys_fn_id  then
  1248.     write('function');
  1249.  
  1250.   with info^ do
  1251.   begin
  1252.     write(oneindent,name,tab,'{ Special index ',hexbyte(addr_ofs));
  1253.     if flags <> 0 then
  1254.       write(oneindent,'Flags ',hexbyte(flags));  { What are those flags!!??! }
  1255.     writeln(' }');
  1256.   end;
  1257.   last_kind := kind;
  1258. end;
  1259.  
  1260. procedure write_general(kind:byte; title,name,suffix:string);
  1261. begin
  1262.   if last_kind <> kind then
  1263.   begin
  1264.     writeln(title);
  1265.     last_kind := kind;
  1266.     indent;
  1267.   end;
  1268.   write(oneindent,name,suffix);
  1269. end;
  1270.  
  1271. procedure print_obj(obj:obj_ptr);
  1272. var
  1273.   j:word;
  1274.   obj_info : ^byte_array;
  1275.   new_entry : list_ptr;
  1276.   info_len,info_ofs : word;
  1277.   obj_type : byte;
  1278. const
  1279.   dump_types  : set of byte = [];
  1280. begin
  1281.   info_ofs := sizeof(obj_rec)-sizeof(string)+1+length(obj^.name);
  1282.   obj_info := add_only_offset(obj,info_ofs);
  1283.   obj_type := obj^.obj_type;
  1284.   if (obj_type and $80) <> 0 then
  1285.   begin
  1286.     if last_kind <> objpriv_id then
  1287.     begin
  1288.       dec(indentation);
  1289.       indent;
  1290.       inc(indentation);
  1291.       writeln('private');
  1292.       last_kind := objpriv_id;
  1293.     end;
  1294.     obj_type := obj_type and $7F;
  1295.   end;
  1296.  
  1297.   if obj_type in known_types then
  1298.   begin
  1299.     if last_kind<>obj_type then
  1300.     begin
  1301.       if (obj_type<>const_id) and (NowEnum<>nil) then
  1302.       begin
  1303.         if last_kind=const_id then
  1304.           Writeln('*)');
  1305.         NowEnum:=nil;
  1306.       end;
  1307.       if last_kind=unit_id then
  1308.         writeln(';');
  1309.     end;
  1310.     if obj_type=const_id then
  1311.     begin
  1312.       write_const_info(obj^.name,pointer(obj_info));
  1313.     end
  1314.     else if obj_type=type_id then
  1315.     begin
  1316.       write_type_info(obj^.name,obj,pointer(obj_info));
  1317.     end
  1318.     else if obj_type=var_id then
  1319.     begin
  1320.       write_var_info(obj^.name,pointer(obj_info));
  1321.     end
  1322.     else if obj_type=proc_id then
  1323.     begin
  1324.       write_proc_info(obj^.name,pointer(obj_info));
  1325.       if not (last_kind in [object_id,objpriv_id]) then
  1326.         last_kind := proc_id;
  1327.     end
  1328.     else if (obj_type=sys_proc_id) or (obj_type=sys_fn_id) then
  1329.     begin
  1330.       write_system_type(obj^.name,obj_type,pointer(obj_info));
  1331.     end
  1332.     else if obj_type=sys_port_id then
  1333.     begin
  1334.       write_general(sys_port_id,'type {port array}',obj^.name,':'+oneindent);
  1335.       if byte_array_ptr(obj_info)^[0]=0 then
  1336.         writeln('Byte;')
  1337.       else
  1338.         writeln('Word;')
  1339.     end
  1340.     else if obj_type=sys_mem_id then
  1341.     begin
  1342.       write_general(sys_mem_id,'type {memory array}',obj^.name,':'+oneindent);
  1343.       write_type_def(add_only_offset(buffer,type_info_ptr(obj_info)^.type_def_ofs));
  1344.       writeln(';');
  1345.     end
  1346.     else if obj_type=sys_new_id then
  1347.     begin
  1348.       write_general(sys_new_id,'system allocator '+obj^.name+';','',#13#10);
  1349.     end
  1350. {$IFNDEF UNIT60}
  1351.     else if obj_type=sys_openstr_id then
  1352.     begin
  1353.       write_general(sys_openstr_id,'system open string type:'+obj^.name+';','',#13#10);
  1354.     end
  1355. {$ENDIF}
  1356.     else if obj_type=unit_id then
  1357.     begin
  1358.       write_unit_info(obj^.name,pointer(obj_info),
  1359.                      obj_ofs(obj) = header^.ofs_this_unit)
  1360.     end;
  1361.   end
  1362.   else
  1363.   begin
  1364.     WriteError('Unknown kind '+DecWord(obj_type)+oneindent+obj^.name+
  1365.                ' with info at '+hexword(obj_ofs(obj_info)));
  1366.     last_kind := obj_type;
  1367.   end;
  1368.   if obj_type in dump_types then
  1369.   begin
  1370.     for j:=0 to 15 do
  1371.       write(hexword(obj_ofs(obj_info)+j):5);
  1372.     for j:=0 to 15 do
  1373.       write(hexbyte(obj_info^[j]):5);
  1374.     for j:=16 to 31 do
  1375.       write(hexword(obj_ofs(obj_info)+j):5);
  1376.     for j:=16 to 31 do
  1377.       write(hexbyte(obj_info^[j]):5);
  1378.   end;
  1379. end;
  1380.  
  1381. procedure print_name_list(obj_list:list_ptr);
  1382. var
  1383.   obj : obj_ptr;
  1384.   current : list_ptr;
  1385.   bytes : ^byte_array;
  1386.   j : integer;
  1387. begin
  1388.   last_kind := init_id;
  1389.   current := obj_list;
  1390.   while current^.offset < $ffff do
  1391.   begin
  1392.     obj := add_only_offset(buffer,current^.offset);
  1393.     print_obj(obj);
  1394.     current := current^.next;
  1395.   end;
  1396. end;
  1397.  
  1398. end.
  1399.